#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"

extern "C"
{
#include "can/can_msg.h"
}

static struct CanMsgPool *g_pool;

TEST_GROUP(can_msg_test)
{
    void setup()
    {
        g_pool = CanMsgPoolCreate(8); // 8, pool size
        CHECK_FALSE(g_pool == NULL);
    }

    void teardown()
    {
        CanMsgPoolDestroy(g_pool);
        mock("IO").checkExpectations();
        mock().clear();
    }
};

TEST(can_msg_test, should_obtain_and_put_msg_without_mem_leak)
{
    struct CanMsg *msg = NULL;
    msg = CanMsgPoolObtainMsg(g_pool);
    CHECK_FALSE(msg == NULL);
    CanMsgPut(msg);
}

TEST(can_msg_test, should_get_and_put_msg_without_mem_leak)
{
    struct CanMsg *msg = NULL;
    msg = CanMsgPoolObtainMsg(g_pool);
    CHECK_FALSE(msg == NULL);
    CanMsgGet(msg);
    CanMsgPut(msg);
    CanMsgPut(msg);
}

TEST(can_msg_test, should_get_the_same_msg_cached_in_pool)
{
    struct CanMsg *msg1 = NULL;
    struct CanMsg *msg2 = NULL;
    msg1 = CanMsgPoolObtainMsg(g_pool);
    CHECK_FALSE(msg1 == NULL);
    CanMsgPut(msg1);
    msg2 = CanMsgPoolObtainMsg(g_pool);
    CHECK_TRUE(msg2 == msg1);
    CanMsgPut(msg2);
}

TEST(can_msg_test, should_get_new_msg_if_previous_not_released)
{
    struct CanMsg *msg1 = NULL;
    struct CanMsg *msg2 = NULL;
    msg1 = CanMsgPoolObtainMsg(g_pool);
    CHECK_FALSE(msg1 == NULL);
    msg2 = CanMsgPoolObtainMsg(g_pool);
    CHECK_TRUE(msg2 != msg1);
    CanMsgPut(msg1);
    CanMsgPut(msg2);
}
